﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace OS.Common.Extention.Volidate
{
    /// <summary>
    /// 有效性校验扩展
    /// </summary>
    public static class VolidateExtention
    {
        /// <summary>
        /// 是否通过验证
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="t">实体对象</param>
        /// <returns><c>true</c><value>校验正确</value><c>false</c><value>校验失败</value></returns>
        public static bool IsLValidate<T>(this T t) where T : class, new()
        {
            if (t == null)
            {
                return false;
            }

            var typeFromHandle = typeof(T);
            var properties = TypeHelper.GetProperties(typeFromHandle);
            foreach (var propertyInfo in properties)
            {
                var propertiAttributes = TypeHelper.GetPropertiAttributes(typeFromHandle.FullName, propertyInfo,
                    typeof(BaseValidateAttribute));

                if (propertiAttributes.OfType<BaseValidateAttribute>().Any((BaseValidateAttribute requireAttribute) =>
                    !requireAttribute.Validate(propertyInfo.Name, propertyInfo.GetValue((T) t, null))))
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 返回的验证错误信息
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="t">实体对象</param>
        /// <returns>错信信息集合</returns>
        public static List<string> ValidateMessage<T>(this T t) where T : class, new()
        {
            var list = new List<string>();
            if (t == null)
            {
                list.Add("对象不能为空！");
                return list;
            }

            var typeFromHandle = typeof(T);
            var properties = TypeHelper.GetProperties(typeFromHandle);
            foreach (var propertyInfo in properties)
            {
                var propertiAttributes = TypeHelper.GetPropertiAttributes(typeFromHandle.FullName, propertyInfo,
                    typeof(BaseValidateAttribute));

                using (IEnumerator<BaseValidateAttribute> enumerator = (from requireAttribute in propertiAttributes.OfType<BaseValidateAttribute>() let result = requireAttribute.Validate(propertyInfo.Name, propertyInfo.GetValue((T)t, null)) where !result select requireAttribute).GetEnumerator())
                {
                    if (!enumerator.MoveNext()) continue;
                    var current = enumerator.Current;
                    list.Add(current.ErrorMessage);
                }
            }

            return list;
        }
    }
}